#ifndef __ACC_MMA7455__
#define __ACC_MMA7455__

#include <SoftI2C.h>

//	MMA7455L I2C default address
#define MMA7455_DEVICE_ADDRESS		0x1D

// MMA7455L registers
//	10 bits Output Value X LSB (Read only)
#define ACC_REG_XOUTL			0x00
//	10 bits Output Value X MSB (Read only)
#define ACC_REG_XOUTH			0x01
//	10 bits Output Value Y LSB (Read only)
#define ACC_REG_YOUTL			0x02
//	10 bits Output Value Y MSB (Read only)
#define ACC_REG_YOUTH			0x03
//	10 bits Output Value Z LSB (Read only)
#define ACC_REG_ZOUTL			0x04
//	10 bits Output Value Z MSB (Read only)
#define ACC_REG_ZOUTH			0x05

//	8bits Output Value X (Read only)
#define ACC_REG_XOUT8			0x06
//	8bits Output Value Y (Read only)
#define ACC_REG_YOUT8			0x07
//	8bits Output Value Z (Read only)
#define ACC_REG_ZOUT8			0x08
//	Status Register (RO)
#define ACC_REG_STATUS			0x09
	#define ACC_DRDY			0x01	// 1: Data is ready
	#define ACC_DOVR			0x02	// 1: Data is not over written
	#define ACC_PERR			0x04	// 1: Parity error is detected in trim data. Then, self-test is disabled
//	Detection Source Register (Read only)
#define ACC_REG_DETSRC			0x0A
	#define ACC_SRC_INT1		0x01	// 1: Interrupt assigned by INTRG[1:0] bits in Control 1 Register ($18) and is detected
	#define ACC_SRC_INT2		0x02	// 1: Interrupt assigned by INTRG[1:0] bits in Control 1 Register ($18) and is detected
	#define ACC_PULSE_DZ		0x04	// 1: Pulse is detected on Z-axis at single pulse detection
	#define ACC_PULSE_DY		0x08	// 1: Pulse is detected on Y-axis at single pulse detection
	#define ACC_PULSE_DX		0x10	// 1: Pulse is detected on X-axis at single pulse detection
	#define ACC_LEVEL_DZ		0x20	// 1: Level detection detected on Z-axis
	#define ACC_LEVEL_DY		0x40	// 1: Level detection detected on Y-axis
	#define ACC_LEVEL_DX		0x80	// 1: Level detection detected on X-axis
//	Temperature output value (Optional)
#define ACC_REG_TOUT			0x0B
//	I2C Device Address (Bit 6-0: Read only, Bit 7: Read/Write)
#define ACC_REG_I2CAD			0x0D
	#define ACC_I2CDIS			0x80	// 1: I2C is disabled.
//	User Information (Read Only: Optional)
#define ACC_REG_USRINF			0x0E	// 0xAA
//	"Who Am I" Value (Read only: Optional)
#define ACC_REG_WHOAMI			0x0F	// 0x55

//	Offset Drift X LSB (Read/Write)
#define ACC_REG_XOFFL			0x10
//	Offset Drift X MSB (Read/Write)
#define ACC_REG_XOFFH			0x11
//	Offset Drift Y LSB (Read/Write)
#define ACC_REG_YOFFL			0x12
//	Offset Drift Y MSB (Read/Write)
#define ACC_REG_YOFFH			0x13
//	Offset Drift Z LSB (Read/Write)
#define ACC_REG_ZOFFL			0x14
//	Offset Drift Z MSB (Read/Write)
#define ACC_REG_ZOFFH			0x15
//	Mode Control Register (Read/Write)
#define ACC_REG_MCTL			0x16
	#define	ACC_MODE_STANDBY	0x00	// MODE[1:0]
	#define	ACC_MODE_MEASURE	0x01
	#define	ACC_MODE_LEVEL		0x02
	#define	ACC_MODE_PULSE		0x03
	#define ACC_SEL_8G			0x00	// GLVL[1:0]
	#define ACC_SEL_2G			0x04
	#define ACC_SEL_4G			0x08
	#define ACC_STON			0x10	// Self-test is enabled
	#define ACC_SPI3W			0x20	// 0: SPI is 4 wire mode
										// 1: SPI is 3 wire mode
	#define ACC_DRPD			0x40	// 1: Data ready status is not output to INT1/DRDY PIN
//	Interrupt Latch Reset (Read/Write)
#define ACC_REG_CLR_INT			0x17
	#define ACC_CLR_INT1		0x01	// 1: Clear INT1 and LDX/LDY/LDZ or PDX/PDY/PDZ bits in Detection Source Register ($0A) depending on Control1($18) INTREG[1:0] setting.
										// 0: Do not clear INT1 LDX/LDY/LDZ or PDX/PDY/PDZ bits in Detection Source Register ($0A)
	#define ACC_CLR_INT2		0x02	// 1: Clear INT2 and LDX/LDY/LDZ or PDX/PDY/PDZ bits in Detection Source Register ($0A) depending on Control1($18) INTREG[1:0] setting.
										// 0: Do not clear INT2 and LDX/LDY/LDZ or PDX/PDY/PDZ bits in Detection Source Register ($0A).
//	Control 1 (Read/Write)
#define ACC_REG_CTL1			0x18
	#define ACC_INTPIN			0x01
	#define ACC_INTREG_0		0x00
	#define ACC_INTREG_1		0x02
	#define ACC_INTREG_2		0x04
	#define ACC_INTREG_3		0x06
	#define ACC_XDA				0x08	// 1: X-axis is disabled for detection
	#define ACC_YDA				0x10	// 1: Y-axis is disabled for detection
	#define ACC_ZDA				0x20	// 1: Z-axis is disabled for detection
	#define ACC_THOPT			0x40	// (This bit is valid for level detection only, not valid for pulse detection)
 										// 0: Threshold value is absolute only
 										// 1: Integer value is available.
	#define ACC_DFBW			0x80	// 0: Digital filter band width is 62.5 Hz
										// 1: Digital filter band width is 125 Hz
//	Control 2 (Read/Write)
#define ACC_REG_CTL2			0x19
	#define ACC_LDPL			0x01	// 0: Level detection polarity is positive and detecting condition is OR 3 axes
										// 1: Level detection polarity is negative detecting condition is AND 3 axes
	#define ACC_PDPL			0x02	// 0: Pulse detection polarity is positive and detecting condition is OR 3 axes
										// 1: Pulse detection polarity is negative and detecting condition is AND 3 axes
	#define ACC_DRVO			0x04	// 0: Standard drive strength on SDA/SDO pin
										// 1: Strong drive strength on SDA/SDO pin
//	Level Detection Threshold Limit Value (Read/Write)
#define ACC_REG_LDTH			0x1A
//	Pulse Detection Threshold Limit Value (Read/Write)
#define ACC_REG_PDTH			0x1B
//	Pulse Duration Value (Read/Write)
#define ACC_REG_PW				0x1C	// Min: PD[7:0] = 4РІР‚в„ўh01 = 0.5 ms
										// Max: PD[7:0] = 4РІР‚в„ўhFF = 127 ms
										// 1 LSB = 0.5 ms
//	Latency Time Value (Read/Write)
#define ACC_REG_LT				0x1D
//	Time Window for 2nd Pulse Value (Read/Write)
#define ACC_REG_TW				0x1E

// void xgpio_write_bit(PinIO pin, uint8 val);
// uint32 xgpio_read_bit(PinIO pin);
// void xgpio_set_mode(PinIO pin, uint8 mode);

enum {
	MMA7455_OK			= SI2C_SUCCESS,
	MMA7455_NOT_READY	= 0x80,
	MMA7455_INITIAL		= 0x81,
	MMA7455_NOT_FOUND	= 0x82,
	MMA7455_INIT_ERROR	= 0x83
};


class MMA7455
{
public:
	MMA7455(void);

	uint8 begin(void);
	uint8 begin(SoftI2C *);
	uint8 begin(uint8 mode);
	uint8 begin(SoftI2C *, uint8 mode);
	uint8 end(void);

	uint8 readXYZ(void);

	uint8 write(uint8 address, uint8 data);
	uint8 read(uint8 address);

	uint8 Data;
	uint8 Error;
	uint8 Mode;
	int16 X;
	int16 Y;
	int16 Z;

	uint8 DeviceAddress;

private:
	uint8 PinInt1;
	uint8 PinInt2;
	SoftI2C *I2C;
};

#endif
